package ar.edu.ufasta.presupuestos.servicios.web;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.StringTokenizer;

import ar.edu.ufasta.presupuestos.servicios.web.netpacks.InfoClienteRequest;
import ar.edu.ufasta.presupuestos.servicios.web.netpacks.InfoPresupuestoRequest;
import ar.edu.ufasta.presupuestos.servicios.web.netpacks.ListaPresupuestoRequest;
import ar.edu.ufasta.presupuestos.servicios.web.netpacks.ListaPresupuestoResponse;
import ar.edu.ufasta.presupuestos.servicios.web.netpacks.LoginRequest;
import ar.edu.ufasta.presupuestos.servicios.web.netpacks.RequestPack;
import ar.edu.ufasta.presupuestos.servicios.web.netpacks.ResponsePack;
import ar.edu.ufasta.presupuestos.servicios.web.netpacks.TransaccionPresupuestoRequest;

public class ClientConnection extends Thread {

	private Socket clientSocket;
	private ObjectInputStream inputChannel;
	private ObjectOutputStream outputChannel;
	private BufferedReader inputString;
	private PrintWriter outputString;
	
	public ClientConnection(Socket accept) {
		this.clientSocket = accept;
	}

	@Override
	public void run() {
		try {
			LogFile.write("---- Remote client connected : " + clientSocket.getInetAddress() + " ----");
			
			inputString = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
			outputString = new PrintWriter(this.clientSocket.getOutputStream(),true);
			
			String toReceive = inputString.readLine();
			LogFile.write("---- Received string pack: "+toReceive);
			processRequest(toReceive);			
						
			clientSocket.shutdownInput();
			clientSocket.shutdownOutput();
			clientSocket.close();
			LogFile.write("---- Remote cliente disconnected ----");
			LogFile.write("===========================================================");
		} catch (Exception e) {
			try {
				clientSocket.close();
				
			} catch (IOException e1) {
				LogFile.write("**** Error on remote host disconnect ****");
			}
			LogFile.write("**** Error reading client socket ****");
			e.printStackTrace();			
		}		
	}
	
	private void processRequest(String tramaReceived){
		// 1 variable por familia de protocolos que puede admitir el servicio
		Protocol protocol = null;
		ResponsePack responsePack = null;
		RequestPack requestPack = null;
		//int codeOperation = requestPack.getOperationCode();
		//***********************************************************
		StringTokenizer st = new StringTokenizer(tramaReceived,";");
		st.countTokens();
		int proto = Integer.valueOf(st.nextToken());
		int sysCode = Integer.valueOf(st.nextToken());
		int codeOperation = Integer.valueOf(st.nextToken());
		//***********************************************************
		requestPack = StaticRequestFactory.getInstancia().makeRequestPack(proto, codeOperation);
		protocol = StaticOperationFactory.getInstancia().makeOperationCommand(proto, codeOperation);
		try {
			LogFile.write(protocol.getOperationMsg());
			requestPack.setTrama(tramaReceived);
			requestPack.decodificarTrama();
			protocol.setPedido(requestPack);
			protocol.execute();
			responsePack = protocol.getRespuesta();
			responsePack.codificarTrama();
			String toSend = responsePack.getTrama();
			outputString.println(toSend);
			outputString.flush();
			LogFile.write("---- Sended response string: "+toSend);
		} catch (Exception e) {
			LogFile.write("**** Error sending response object ****");
		}
	}

}
